﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ndo.Maths
{
    public delegate double DistanceHandler<Vector>(Vector a1, Vector a2) where Vector : IList<double>;
    public static class Measure
    {
        public static double EuclideanDistance(IList<double> a1, IList<double> a2)
        {
            if (a1.Count != a2.Count)
                throw new Exception();
            double a = 0;
            for (int i = 0; i < a1.Count; i++)
            {
                double t = a1[i] - a2[i];
                a += t*t;
            }
            return Math.Sqrt(a);
        }
        public static double AdditionDistance(IList<double> a1, IList<double> a2)
        {
            if (a1.Count != a2.Count)
                throw new Exception();
            double a = 0;
            for (int i = 0; i < a1.Count; i++)
            {
                a += Math.Abs(a1[i] - a2[i]);
            }
            return a;
        }
        public static double MultiplicationDistance(IList<double> a1, IList<double> a2)
        {
            if (a1.Count != a2.Count)
                throw new Exception();
            double a = 0;
            for (int i = 0; i < a1.Count; i++)
            {
                a *= Math.Abs(a1[i] - a2[i]);
            }
            return a;
        }
        public static double Entropy(IEnumerable<double> data)
        {
            double total = 0;
            foreach (int i in data)
                if (i >= 0)
                {
                    total += i;
                }
            double ret = 0;
            foreach (int i in data)
                if (i > 0)
                {
                    double p = i / total;
                    ret -= p * Math.Log(p);
                }
            return ret;
        }
        public static double Entropy(IEnumerable<int> data)
        {
            double total = 0;
            foreach (int i in data)
                if (i >= 0)
                {
                    total += i;
                }
            double ret = 0;
            foreach (int i in data)
                if (i > 0)
                {
                    double p = i / total;
                    ret -= p * Math.Log(p);
                }
            return ret;
        }
    }

}
